package org.piggy.core;

import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.piggy.common.constants.GatewayConst;
import org.piggy.common.utils.SystemUtil;
import org.piggy.core.netty.NettyHttpClient;
import org.piggy.core.netty.NettyHttpServer;
import org.piggy.core.netty.processor.DisruptorNettyProcessor;
import org.piggy.core.netty.processor.DefaultNettyProcessor;
import org.piggy.core.netty.processor.NettyProcessor;

public class Container implements LifeCycle {

    private final Config config;

    private NettyHttpServer nettyHttpServer;

    private NettyHttpClient nettyHttpClient;

    public Container(Config config) {
        this.config = config;
        init();
    }

    @Override
    public void init() {
        NettyProcessor nettyProcessor;
        DefaultNettyProcessor defaultNettyProcessor = new DefaultNettyProcessor();
        if(GatewayConst.PROCESSOR_TYPE.equals(config.getProcessorType())){
            nettyProcessor = new DisruptorNettyProcessor(config, defaultNettyProcessor);
        }else{
            nettyProcessor = defaultNettyProcessor;
        }
        this.nettyHttpServer = new NettyHttpServer(config, nettyProcessor);

        EventLoopGroup eventLoopGroup;
        if (SystemUtil.isLinuxPlatform() && Epoll.isAvailable()) {
            eventLoopGroup = new EpollEventLoopGroup(config.getEventLoopGroupWorkerNum(),
                    new DefaultThreadFactory("http-client-epoll"));
        } else {
            eventLoopGroup = new NioEventLoopGroup(config.getEventLoopGroupWorkerNum(),
                    new DefaultThreadFactory("http-client-nio"));
        }
        this.nettyHttpClient = new NettyHttpClient(config, eventLoopGroup);
    }

    @Override
    public void start() {
        nettyHttpServer.start();;
        nettyHttpClient.start();
    }

    @Override
    public void shutdown() {
        nettyHttpServer.shutdown();
        nettyHttpClient.shutdown();
    }

}
